package eu.robico.simulator.simulatorinterface.communication;

public class Protocol 
{
	public static class Type
	{
		public static final String DISCONNECT = "disconnect";
		public static final String TRIGGER = "trigger";
		public static final String UPDATE = "update";
	}
	
	public static enum Trigger
	{
		//0 - 99 = signals
		EMERGENCYSIGNAL(0),
		PROXIMITYSIGNAL(1),
		COLLISIONFRONTSIGNAL(2),
		COLLISIONBACKSIGNAL(3),
		COLORLANELEFTSIGNAL(4),
		COLORLANERIGHTSIGNAL(5),
		CROSSROADSSIGNAL(6),
		SIDEEXITLEFTSIGNAL(7),
		SIDEEXITRIGHTSIGNAL(8),
		// 100 - 199 = toggles
		EMERGENCYTOGGLE(100),
		PROXIMITYTOGGLE(101),
		COLLISIONFRONTTOGGLE(102),
		COLLISIONBACKTOGGLE(103),
		COLORLANELEFTTOGGLE(104),
		COLORLANERIGHTTOGGLE(105),
		CROSSROADSTOGGLE(106),
		SIDEEXITLEFTTOGGLE(107),
		SIDEEXITRIGHTTOGGLE(108),
		
		//200 - 299 = (server) commands
		START(200),
		PAUZE(201),
		RESTART(202);
		
		private int value;
		
		Trigger(int value)
		{
			this.value = value;
		}
		
		public int getValue()
		{
			return value;
		}
		
		public String getType()
		{
			return "trigger";
		}
		
		public static Trigger valueOf(int value)
		{
			for (Trigger t : Trigger.values())
				if (t.value == value)
					return t;
			throw new IllegalArgumentException("No such Trigger exists");
		}
		
	}
	
	public static enum UpdateType
	{
		STATUS(0),
		LEFTWHEEL(1),
		RIGHTWHEEL(2),
		LED1(3),
		LED2(4),
		BUZZER(5),
		SLEEP(6),
		WHEELCONTROL(7),
		COLORLANELEFTSENSOR(8),
		COLORLANERIGHTSENSOR(9),
		EMERGENCYSENSOR(10),
		PROXIMITYSENSOR(11),
		COLLISIONFRONTSENSOR(12),
		COLLISIONBACKSENSOR(13),
		CROSSROADSSENSOR(14),
		SIDEEXITLEFTSENSOR(15),
		SIDEEXITRIGHTSENSOR(16),
		
		CONNECTION(100),
		CONNECTIONERROR(101);
		
		private int value;
		
		UpdateType(int value)
		{
			this.value = value;
		}
		
		public int getValue()
		{
			return value;
		}
		
		public static final String type = "update";
		public static String getType()
		{
			return type;
		}
		
		public static UpdateType valueOf(int value)
		{
			for (UpdateType ut : UpdateType.values())
				if (ut.value == value)
					return ut;
			throw new IllegalArgumentException("No such UpdateType exists");
		}
	}
	
	public static enum WheelStatus
	{
		STOPPED(0),
		FORWARD(1),
		BACKWARD(2);
		
		private int value;
		
		WheelStatus(int value)
		{
			this.value = value;
		}
		
		public int getValue()
		{
			return value;
		}
		
		public static WheelStatus valueOf(int value)
		{
			for (WheelStatus ws : WheelStatus.values())
				if (ws.value == value)
					return ws;
			throw new IllegalArgumentException("No such UpdateType exists");
		}
		
		public String toString()
		{
			switch (this)
			{
			case BACKWARD: return "Backward";
			case FORWARD: return "Forward";
			case STOPPED: return "Stopped";
			default: throw new RuntimeException();
			}
		}
	}
	
	public static enum SimulationStatus
	{
		RUNNING(0),
		PAUZED(1),
		STOPPED(2);
		
		private int value;
		
		SimulationStatus(int value)
		{
			this.value = value;
		}
		
		public int getValue()
		{
			return value;
		}
		
		public static SimulationStatus valueOf(int value)
		{
			for (SimulationStatus ss : SimulationStatus.values())
				if (ss.value == value)
					return ss;
			throw new IllegalArgumentException("No such UpdateType exists");
		}
		
		public String toString()
		{
			switch (this)
			{
			case RUNNING: return "Running";
			case PAUZED: return "Pauzed";
			case STOPPED: return "Stopped";
			default: throw new RuntimeException();
			}
		}
	}
	
	public static class Update<T> 
	{	
		private UpdateType type;
		public UpdateType getType()
		{
			return type;
		}
		
		private T update;
		public T getUpdate()
		{
			return update;
		}
		
		public Update(UpdateType type, T update)
		{
			this.type = type;
			this.update = update;
		}
	}
}
